package com.l2jserver.gameserver.handler.admin;

import java.util.StringTokenizer;
import java.util.logging.Logger;

import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.util.Util;

/**
 * Creo una clase general para controlar los admin command handlers La idea es dividir a cada comando en su propio archivo, con su lista de parametros y otras opciones. El StringTokenizer seria para todos, habria control de excepciones general, envio de mensajes de uso apropiado automatico, etc
 * @author Synerge
 */
public abstract class AbstractAdminCommandHandler implements IAdminCommandHandler
{
	protected static final Logger _log = Logger.getLogger(AbstractAdminCommandHandler.class.getName());
	
	@Override
	public boolean useAdminCommand(String command, L2PcInstance activeChar)
	{
		try
		{
			final StringTokenizer st = new StringTokenizer(command);
			st.nextToken();
			
			if (!useAdminCommand(command, activeChar, st))
			{
				throw new Exception();
			}
			
			// Si debe enviar el menu al finalizar exitosamente, lo enviamos
			if (mustShowMenu())
			{
				showMainMenu(activeChar);
			}
			return true;
		}
		catch (Exception e)
		{
			activeChar.sendMessage("Usage: //" + getAdminCommand().substring(6) + " " + Util.joinArrayWithCharacter(getCommandParameters(), "|"));
		}
		
		// Si pasa algo malo, enviamos el menu principal de nuevo, si es que tiene uno
		showMainMenu(activeChar);
		
		return false;
	}
	
	/**
	 * @param activeChar
	 * @param target
	 * @return Devuelve true si el pj puede usar este comando sobre el target. Se hacen chequeos como por ejemplo diferencia de rangos entre gms
	 */
	protected boolean canUseCommandOnTarget(L2PcInstance activeChar, L2PcInstance target)
	{
		// Un GM no puede usar un comando negativo sobre un gm de mas rango
		if (activeChar.getAccessLevel().getLevel() < target.getAccessLevel().getLevel())
		{
			return false;
		}
		
		return true;
	}
	
	@Override
	public String[] getAdminCommandList()
	{
		return new String[]
		{
			getAdminCommand()
		};
	}
	
	/**
	 * @return Devuelve el nombre del comando sin el admin_, o sea en vez de admin_gmshop devuelve gmshop
	 */
	public final String getCommandName()
	{
		return getAdminCommand().substring(getAdminCommand().indexOf("_") + 1);
	}
	
	/**
	 * @return Devuelve el nombre de la categoria de este handler. O sea el nombre del package donde se encuentra el mismo
	 */
	public final String getCategoryName()
	{
		final String packageName = getClass().getPackage().getName();
		return packageName.substring(packageName.lastIndexOf(".") + 1);
	}
	
	/**
	 * Se hace override en cada comando que tenga que enviar un menu Lo creo asi para poder llamarlo de emergencia cuando algo tira error y sale con un exception
	 * @param activeChar
	 */
	protected void showMainMenu(L2PcInstance activeChar)
	{
	}
	
	/**
	 * @return Se hace override en cada handler, dependiendo si se debe enviar o no el menu de showMainMenu si es exitoso
	 */
	protected boolean mustShowMenu()
	{
		return false;
	}
	
	/**
	 * @param command
	 * @param activeChar
	 * @param st
	 * @return Seria el useAdmin de siempre, solo que ademas tiene un parametro de string tokenizer para ahorrar pasos. Devuelve true si no hubo errores
	 */
	public abstract boolean useAdminCommand(String command, L2PcInstance activeChar, StringTokenizer st);
	
	/**
	 * @return Devuelve el nombre del comando admin relacionado con este handler
	 */
	public abstract String getAdminCommand();
	
	/**
	 * @return Devuelve la lista de parametros o acciones posibles para el comando
	 */
	public abstract String[] getCommandParameters();
	
	/**
	 * @return Devuelve una descripcion pequeña de lo que hace este handler/comando
	 */
	public abstract String getCommandDescription();
}
